﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using OpenQuarters.WebQuarters.Utils;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace OpenQuarters.WebQuarters.Core
{
    [Serializable]
    public class ModuleDefinition
    {
        private string moduleType = "";

        public string ModuleType
        {
            get { return moduleType; }
            set { moduleType = value; }
        }

        private string moduleJSON = "{}";

        public string ModuleJSON
        {
            get { return moduleJSON; }
            set { moduleJSON = value; }
        }

        public string JQueryEditorName
        {
            get
            {
                try
                {
                    return ((Module)Activator.CreateInstance(GeneralUtils.GetTypeByName(this.ModuleType))).GetJQueryEditorName();
                }
                catch
                {
                    return new ModuleErrorModule().GetJQueryEditorName();
                }
            }
            set { }
        }

        public string ModuleName
        {
            get
            {
                try
                {
                    return ((Module)Activator.CreateInstance(GeneralUtils.GetTypeByName(this.ModuleType))).ModuleName;
                }
                catch
                {
                    return new ModuleErrorModule().ModuleName;
                }
            }
            set { }
        }

        /// <summary>
        /// Produces camel case version of Module Name
        /// </summary>
        public string ModuleNameClassSafe
        {
            get { return Utils.GeneralUtils.ToCamelCase(ModuleName); }
        }

        public string UniqueID
        {
            get
            {
                return Guid.NewGuid().ToString().Replace("-", "_");
            }
            set { }
        }

        private bool isInherited = false;

        public bool IsInherited
        {
            get { return isInherited; }
            set { isInherited = value; }
        }

        public ModuleDefinition()
        {
        }

        public ModuleDefinition(Module module)
        {
            this.ModuleJSON = GeneralUtils.ToJSON(module);
            this.ModuleType = module.GetType().FullName;
        }

        public Module InstantiateIn(Control parentCtl)
        {
            HtmlGenericControl ctl = new HtmlGenericControl("div");
            ctl.Attributes.Add("class", "cmsModule " + this.ModuleNameClassSafe + (IsInherited ? " cmsInherited" : ""));
            parentCtl.Controls.Add(ctl);

            object moduleObj = null;
            Type moduleType = GeneralUtils.GetTypeByName(this.ModuleType);
            if (moduleType == null)
            {
                moduleObj = new Core.ModuleErrorModule()
                {
                    ErrorType = OpenQuarters.WebQuarters.Core.ModuleErrorModule.ModuleErrorModuleError.Could_Not_Find_Module_Type,
                    Value = this.ModuleType
                };
            }
            else
            {
                try
                {
                    moduleObj = Activator.CreateInstance(moduleType);
                    typeof(GeneralUtils).GetMethod("FromJSON", new Type[] { typeof(string), typeof(object) }).MakeGenericMethod(moduleType).Invoke(null, new object[] { this.ModuleJSON, moduleObj });
                }
                catch (Exception ex)
                {
                    moduleObj = new Core.ModuleErrorModule()
                    {
                        ErrorType = OpenQuarters.WebQuarters.Core.ModuleErrorModule.ModuleErrorModuleError.Exception,
                        Value = "<pre>" + ex.GetExceptionInfo() + "</pre>"
                    };
                }
            }
            ctl.Controls.Add((Core.Module)moduleObj);

            if (CMSEnvironment.EditMode)
            {
                this.ModuleJSON = moduleObj.ToJSON();
                ctl.Controls.AddAt(0, new LiteralControl("<textarea style=\"display: none; width: 400px; height: 150px;\" class=\"cmsModuleConfig\">" + (this.ModuleJSON == "undefined" ? "{}" : this.ModuleJSON) + "</textarea>"));
                ctl.Controls.AddAt(0, new LiteralControl("<textarea style=\"display: none; width: 400px; height: 150px;\" class=\"cmsModuleDefinition\">" + this.ToJSON() + "</textarea>"));
            }

            return (Core.Module)moduleObj;
        }
    }
}